﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Motoball.screenmanager;
using Motoball.screens;
using Microsoft.Xna.Framework.Input;

namespace Motoball.Paddles
{
    public abstract class PaddleContent
    {
        #region Values
        BasicModel baseModel;
        protected DrawSet set;
        protected string type = "";
        public float initialSpeed = 0.99f;
        public bool movementDisabled = false;
        public PaddleAnimation animation;
        protected float ballInfluence = 0;
        protected float ballMulitplier = 1;
        public float ballHeight = 0f;
        
        public int energyCost = 5;

        
        public float specialMoveTimer = 0f;

        public bool specialMoveActive = false;
        public float weight = 1f;
        public static float defaultWeight = 1f;
        //protected float innerRadius;
        //protected float wheelRadius = 80;
        //protected float rotationsPerRadian;

        //protected float wheelRotation = 0.0f;

        //protected ModelBone leftWheel;
        //protected ModelBone rightWheel;

        protected BoneProperties[] shield;

        //protected Matrix leftWheelTransform;
        //protected Matrix rightWheelTransform;
        protected float bloomValue = 0;
        protected Paddle paddle;
        public float paddleWidth = 0;
        public float paddleHeight = 0;
        /// <summary>
        /// max distance ball-to-paddle-collision has to be checked from
        /// </summary>
        public float maxPaddleDistance = 0;
        #endregion
        #region Methods
        public PaddleContent() { }
        public PaddleContent(Paddle paddle)
        {
            this.paddle = paddle;
            baseModel = paddle.basicModel;
        }
        
        /// <summary>
        /// updates animation and input, activates specialmove as input was done
        /// </summary>
        /// <param name="gameTime"></param>
        /// <returns>returns true if specialMove is inactive false otherwise</returns>
       
        public virtual bool Update(GameTime gameTime)
        {
            animation.Update(gameTime, paddle.Rotation);
            if (!specialMoveActive)
            {
                if (CheckSpecialMovementKeys())
                    if (energyCost <= paddle.energy)
                        SpecialMovement(true);
                    else
                        AudioManager.PlayCue("no_energy");
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool ballHit;
        protected float maxInfluence = 10f;
        public virtual void UpdateAnimation(GameTime gameTime)
        {
            //leftWheel.Transform = Matrix.CreateRotationY(wheelRotation) * leftWheelTransform;
            //rightWheel.Transform = Matrix.CreateRotationY(wheelRotation) * rightWheelTransform;
            if (ballHit)
            {
                ballInfluence += (float)gameTime.ElapsedGameTime.TotalSeconds * 50 * ballMulitplier;
                if (ballInfluence >= maxInfluence)
                    ballMulitplier = -0.5f;
                else if (ballInfluence <= 0f)
                {
                    ballInfluence = 0f;
                    ballMulitplier = 1.5f;
                    ballHit = false;
                }
            }
            foreach (BoneProperties proper in shield)
            {
                proper.modelBone.Transform = Matrix.CreateTranslation(0, 0, -ballInfluence) * proper.sourceTransform;
            }
            
            animation.UpdateAnimation(gameTime);
            animation.Draw(gameTime);
        }
        public virtual void Reset()
        {
            if (set != null)
                SetDrawSet(false);
            weight = defaultWeight;
            bloomValue = 0f;
            
            movementDisabled = false;
            specialMoveTimer = 0f;
            ballHit = false;
            //wheelRotation = (paddle.StartRotation * rotationsPerRadian) % 360.0f;
            foreach(BoneProperties proper in shield)
                proper.modelBone.Transform = proper.sourceTransform;
            ballInfluence = 0;
            ballMulitplier = 1;
            specialMoveActive = false;
            animation.Reset(paddle.StartRotation);
            animation.UpdateColor(paddle.Col3, paddle.basicModel);
        }
        public virtual void Initialize(float innerRadius)
        {
            animation.Initialize(innerRadius, paddle.basicModel.model);
            
            //this.innerRadius = innerRadius;
            //CalcRotPerRadian();
        }

        public virtual void SpecialMovement(bool action)
        {
            GameplayScreen gameplay = (GameplayScreen)GameScreen.screenManager.GetScreen("gameplayScreen");
            
            
            SetDrawSet(action);
            specialMoveActive = action;
            if (action)
            {
                GameplayScreen.screenManager.Input.RumblePad(paddle.PlayerIndex, 0.8f, 0.8f, 2.7f);
                
                gameplay.ball.Color = paddle.Col3;
                paddle.energy -= energyCost;
                paddle.RefreshEnergyDisplay();
            }
            else
                gameplay.ball.Color = Vector3.One;
        }
        /// <summary>
        /// chechks if a special-movementkey was pressed
        /// and decreases energy 
        /// </summary>
        /// <returns>returns true if a spec-mov-key was pressed</returns>
        public bool CheckSpecialMovementKeys()
        {
#if !XBOX
            if (paddle.PlayerIndex == 0 && GameScreen.screenManager.Input.IsNewKeyPress(Keys.Up)
                || paddle.PlayerIndex == 1 && GameScreen.screenManager.Input.IsNewKeyPress(Keys.S))
                return true;
#else
            if (paddle.PlayerIndex == 0)
            {
                if (GameScreen.screenManager.Input.IsNewButtonPress(Buttons.A, PlayerIndex.One))
                    return true;
            }
            else
            {
                if (GameScreen.screenManager.Input.IsNewButtonPress(Buttons.A, PlayerIndex.Two))
                    return true;
            }
#endif
            return false;
        }
        protected void SetDrawSet(bool create)
        {
            GameplayScreen gameplay = (GameplayScreen)GameScreen.screenManager.GetScreen("gameplayScreen");
            if (create)
            {
                GameScreen.screenManager.AddDrawSet(type);
                set = GameScreen.screenManager.GetDrawSet(type);
                set.bloomEnabled = true;
                
                gameplay.ball.model.bloomingMeshes["Ball_Zentrum"] = type;
                baseModel.drawSetId = type;
            }
            else
            {
                GameScreen.screenManager.drawSets.Remove(set);
                set = null;
                baseModel.drawSetId = "default";
                gameplay.ball.model.bloomingMeshes["Ball_Zentrum"] = "default";
            }
        }
        #endregion
        #region Propertiess
        protected float Rotation
        {
            get { return paddle.Rotation; }
        }
        #endregion
    }
  
    
}
